import tkinter as tk
from tkinter import simpledialog

# 创建主窗口
window = tk.Tk()
window.title("To Do List")
window.geometry("800x600")

# 定义列
columns = ["To_Do", "In Progress", "Done"]
frames = {}
cards = []  # 用于存储卡片信息（任务名称、优先级、截止日期、父框架）

# 创建列框架
for col in columns:
    frame = tk.Frame(window, relief=tk.RAISED, borderwidth=1)
    frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    frames[col] = frame
    label = tk.Label(frame, text=col, bg='lightblue', font=('Arial', 12, 'bold'))
    label.pack(fill=tk.X)

# 创建卡片的函数
def create_card(parent_frame, task_name, priority, due_data):
    card_frame = tk.Frame(parent_frame, relief=tk.RAISED, borderwidth=1)
    card_frame.pack(fill=tk.X, pady=5)
    
    task_label = tk.Label(card_frame, text=f"Task: {task_name}", anchor='w')
    task_label.pack(fill=tk.X)
    priority_label = tk.Label(card_frame, text=f"Priority: {priority}", anchor='w')
    priority_label.pack(fill=tk.X)
    due_data_label = tk.Label(card_frame, text=f"Due data: {due_data}", anchor='w')
    due_data_label.pack(fill=tk.X)
    
    edit_button = tk.Button(card_frame, text="edit", command=lambda card=card_frame, name=task_name: edit_task(name, card))
    edit_button.pack(anchor='s')
    delete_button = tk.Button(card_frame, text="delete", command=lambda card=card_frame: delete_card(card))
    delete_button.pack(anchor='s')
    
    card_frame.bind("<Button-1>", lambda event, card=card_frame: on_press(event, card))
    card_frame.bind("<B1-Motion>", lambda event, card=card_frame: on_drag(event, card))
    card_frame.bind("<ButtonRelease-1>", lambda event, card=card_frame: on_release(event, card))
    
    card_info = {
        'frame': card_frame,
        'task_name': task_name,
        'priority': priority,
        'due_data': due_data,
        'original_frame': parent_frame
    }
    cards.append(card_info)

# 卡片按下事件处理函数
def on_press(event, card_frame):
    card_frame._drag_data = {"x": event.x, "y": event.y}
    card_frame.lift()

# 卡片拖动事件处理函数
def on_drag(event, card_frame):
    delta_x = event.x - card_frame._drag_data["x"]
    delta_y = event.y - card_frame._drag_data["y"]
    x = card_frame.winfo_x() + delta_x
    y = card_frame.winfo_y() + delta_y
    card_frame.place(x=x, y=y)

# 卡片释放事件处理函数
def on_release(event, card_frame):
    target_widget = window.winfo_containing(event.x_root, event.y_root)
    for col, frame in frames.items():
        if target_widget == frame or target_widget.winfo_parent() == frame:
            drop(card_frame, frame)
            break
    else:
        for card_info in cards:
            if card_info['frame'] == card_frame:
                drop(card_frame, card_info['original_frame'])
                break

# 卡片放置到新框架的函数
def drop(card_frame, target_frame):
    card_frame.place_forget()
    for card_info in cards:
        if card_info['frame'] == card_frame:
            card_info['original_frame'] = target_frame
            break
    card_frame.pack(fill=tk.X, pady=5)

# 创建卡片的对话框函数（与原来类似，但调用create_card函数）
def create_card_dialog():
    # ...（省略部分代码，与原始代码相同）...
    confirm_button = tk.Button(dialog, text="Confirm", command=lambda: add_task(task_name_var.get(), priority_var.get(), due_data_var.get(), dialog))
    confirm_button.pack(pady=10)

# 添加任务的函数（调用create_card函数）
def add_task(task_name, priority, due_data, dialog):
    if task_name and priority and due_data:
        create_card(frames["To_Do"], task_name, priority, due_data)
    dialog.destroy()

# 删除卡片的函数（与原来类似）
def delete_card(card_frame):
    card_frame.destroy()
    cards[:] = [card_info for card_info in cards if card_info['frame'] != card_frame]

# 编辑任务的函数（与原来类似，但更新卡片信息）
def edit_task(task_name, card_frame):
    new_task_name = simpledialog.askstring("Edit task name", f"Current task: {task_name}\nPlease enter new task name")
    if new_task_name:
        for widget in card_frame.winfo_children():
            if isinstance(widget, tk.Label) and widget.cget('text').startswith("Task:"):
                widget.config(text=f"Task: {new_task_name}")
                for card_info in cards:
                    if card_info['frame'] == card_frame:
                        card_info['task_name'] = new_task_name
                        break

# 创建按钮以打开创建卡片对话框
button = tk.Button(window, text="create", command=create_card_dialog)
button.pack()

window.mainloop()

################################################################################

# 在当前代码中，实现拖动卡片的部分主要涉及以下几个函数和绑定的事件：

# on_press(event, card_frame): 这个函数是卡片按下事件的处理函数。当用户按下鼠标左键时，它会记录按下的位置，并通过card_frame.lift()确保卡片在拖动时显示在最上层。

# on_drag(event, card_frame): 这个函数是卡片拖动事件的处理函数。当用户移动鼠标时，它会计算鼠标移动的距离，并据此更新卡片的位置。这是通过place()方法实现的，该方法允许你精确地指定组件的位置。

# on_release(event, card_frame): 这个函数是卡片释放事件的处理函数。当用户释放鼠标左键时，它会确定卡片应该被放置到哪个列框架中，并调用drop()函数来完成放置操作。

# 绑定事件：在create_card()函数中，有三个关键的事件绑定操作，它们分别将上述三个函数与鼠标左键的按下、移动和释放事件关联起来。这些绑定操作是：

# card_frame.bind("<Button-1>", lambda event, card=card_frame: on_press(event, card))
# card_frame.bind("<B1-Motion>", lambda event, card=card_frame: on_drag(event, card))
# card_frame.bind("<ButtonRelease-1>", lambda event, card=card_frame: on_release(event, card))
# 这些代码片段共同实现了卡片的拖动功能，允许用户通过鼠标将卡片从一个列拖动到另一个列。


################################################################################